class Restaurant:
    def __init__(self, name):
        self.name = name
        self.menu = {}
        self.orders = []

    def display_menu(self):
        """
        展示菜单
        """
        print(f'{self.name:^30}')
        for dish, price in self.menu.items():
            print(f'{dish:<20}{price:>10}')
        print('=' * 30)

    def add_dish(self, dish_name, price):
        """
        添加菜品
        """
        try:
            if dish_name not in self.menu:
                self.menu[dish_name] = int(price)
            else:
                print(f'Error:Dish {dish_name} already exists')
        except ValueError:
            print('Error:Invalid dish price')

    def add_order(self, customer_name, dish_name, quantity):
        """
        添加订单
        """
        if dish_name in self.menu:
            order = self.check_order_customer(customer_name)  # 检查顾客之前是否下过单
            if order:  # 如果该顾客下过单
                if dish_name in order['order']:  # 判断顾客之前点没点过这道菜
                    order['order'][dish_name] += quantity  # 如果点过，数量增加
                    order['total'] += self.menu[dish_name] * quantity
                    print(f'{customer_name} order {dish_name} added successfully.')
                else:
                    order['order'][dish_name] = quantity  # 如果没点过，就增加一项
                    order['total'] += self.menu[dish_name] * quantity
                    print(f'{customer_name} order {dish_name} added successfully.')
            else:  # 如果该顾客没下过单，就创建新订单
                order = {
                    'customer_name': customer_name,
                    'order': {dish_name: quantity},
                    'total': self.menu[dish_name] * quantity}
                self.orders.append(order)
                print(f"{customer_name} order {dish_name} added successfully.")
        else:
            print(f'{dish_name} is not for sale.')

    def check_order_customer(self, customer_name):
        """
        检查顾客是否下过订单，是则返回该订单，不是返回None
        """
        for order in self.orders:
            if customer_name == order['customer_name']:
                return order
        return None

    def display_order(self):
        """
        展示订单
        """
        print('-' * 30)
        print(f'{self.name + ' Order':^30}')
        for order in self.orders:
            print(f'Customer {order["customer_name"]} \'s order:')
            for dish, quantity in order['order'].items():
                print(f'{dish:<15}{quantity}')
            print(f'Total:{order["total"]:^20}')
            print('-' * 30)

    def welcome_message(self):
        """欢迎信息"""
        print(f'Welcome to {self.name}')


class FastFoodRestaurant(Restaurant):
    def __init__(self, name):
        super().__init__(name)
        self.discounts = self.menu  # 使discount指向menu，使快餐店与菜单统一，同时能够使用父类中对menu的操作方法

    def set_discount(self, dish_name, discount_price):
        """
        设置折扣
        """
        try:  # 异常捕获，防止价格为异常值
            if dish_name in self.menu and dish_name in self.discounts:  # 菜品在菜单中，输出修改折扣成功
                self.discounts[dish_name] = int(discount_price)
                print(f'{dish_name} discount modified successfully')
            else:  # 菜品没在菜单里，报错
                print(f'Error:{dish_name} does not exist')
        except ValueError:
            print('Error:Invalid dish price')

    def welcome_message(self):
        """
        欢迎信息
        """
        print(f'Welcome to {self.name}')


if __name__ == '__main__':
    restaurant = Restaurant('Restaurant')
    restaurant.add_dish('chicken', 100)
    restaurant.add_dish('hanberger', 100)
    restaurant.add_dish('french fries', 50)
    restaurant.display_menu()
    restaurant.welcome_message()
    restaurant.add_order('john', 'hanberger', 2)
    restaurant.add_order('john', 'hanberger', 1)
    restaurant.add_order('john', 'chicken', 1)
    restaurant.display_order()

    fast_food_restaurant = FastFoodRestaurant('Fast Restaurant')
    fast_food_restaurant.welcome_message()
    fast_food_restaurant.add_dish('hanberger', 100)
    fast_food_restaurant.add_dish('chicken', 100)
    fast_food_restaurant.set_discount('chicken', 90)
    fast_food_restaurant.set_discount('chicken', 60)
    fast_food_restaurant.add_dish('french fries', 50)
    fast_food_restaurant.set_discount('chicken', '30.')
    fast_food_restaurant.display_menu()

    fast_food_restaurant.add_order('july', 'hanberger', 2)
    fast_food_restaurant.add_order('july', 'hanberger', 1)
    fast_food_restaurant.add_order('july', 'chicken', 1)
    fast_food_restaurant.add_order('july', 'milk', 1)
    fast_food_restaurant.add_order('john', 'hanberger', 2)
    fast_food_restaurant.add_order('john', 'hanberger', 6)
    fast_food_restaurant.add_order('john', 'chicken', 3)
    fast_food_restaurant.display_order()
